package com.globant.rdm;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.QueryBuilder;

import com.globant.rdm.domain.entity.Employee;
import com.globant.rdm.iod.EntityFactory;
import com.globant.rdm.iod.guice.GuiceAwareDomainObjectInjector;
import com.globant.rdm.iod.guice.GuiceAwareEntityFactory;

public class App {

	private static EntityFactory ef = new GuiceAwareEntityFactory(GuiceAwareDomainObjectInjector.getInstance());
	
	public static void main(final String[] args) {

		final EntityManagerFactory emf = Persistence.createEntityManagerFactory("testUnit");
		
		initLuceneIndex(emf);
		
		final EntityManager em = emf.createEntityManager();
		final EntityTransaction et = em.getTransaction();
		
		et.begin();
		
		doInTransaction(em);
		
		et.commit();
		em.close();
		emf.close();
	}

	private static void initLuceneIndex(final EntityManagerFactory emf) {
		final EntityManager em = emf.createEntityManager();
		final FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
		try {
			fullTextEntityManager.createIndexer().startAndWait();
		} catch (final InterruptedException e) {
			e.printStackTrace();
		}
	}

	private static void doInTransaction(final EntityManager em) {
		createMockData(em);
		listAndUpdateTimestamp(em);
		listEmployeesByName(em, "description","*programación*");
		listEmployeesByName(em, "description","*hombría*");	
	}

	private static void listEmployeesByName(EntityManager em, String property, String name) {
		
		final FullTextEntityManager fullTextEntityManager = 
		    org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
		
		final QueryBuilder qb = fullTextEntityManager.getSearchFactory()
	    	.buildQueryBuilder().forEntity( Employee.class ).get();
		final org.apache.lucene.search.Query query = qb.keyword()
			.onFields(property)
			.matching(name)
			.createQuery();

		javax.persistence.Query persistenceQuery =  fullTextEntityManager.createFullTextQuery(query, Employee.class);

		List<?> result = persistenceQuery.getResultList();

		System.out.println(String.format("Buscando por %s = %s .........", property, name));
		
		for (Object r : result) {
			System.out.println(r);
		}
		
	}

	private static void listAndUpdateTimestamp(final EntityManager em) {
		for (final Object eo : em.createQuery("from Employee").getResultList()) {
			final Employee e = (Employee) eo;
			e.updateTimestamp();
			System.out.println(e);
		}
	}

	private static void createMockData(final EntityManager em) {
		if (em.createQuery("from Employee").getResultList().isEmpty()) {
			em.persist(ef.buildEntity(Employee.class).changeName("Julian").setDescription("Me gusta programar"));
			em.persist(ef.buildEntity(Employee.class).changeName("Jose").setDescription("Me encantan los hombres"));
			em.persist(ef.buildEntity(Employee.class).changeName("Ciro"));
			em.persist(ef.buildEntity(Employee.class).changeName("Hector"));
			em.persist(ef.buildEntity(Employee.class).changeName("Mauro"));
		}
	}
	
}
